#include "ble.h"


const char *BLE_TAG = "BLE_CONFIG";

// 定义并初始化全局变量 (分配内存)
my_wifi_config_t wifi_config = {
    .ssid = "",         // 初始化为空字符串
    .password = ""      // 初始化为空字符串
};

my_network_config_t network_config = {
    .ip = "",
    .gateway = "",
    .subnet = ""
};


// 广播参数
static esp_ble_adv_params_t adv_params = {
    .adv_int_min = 0x20,
    .adv_int_max = 0x40,
    .adv_type = ADV_TYPE_IND,
    .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
    .channel_map = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
// 全局变量：记录 BLE 是否已初始化
static bool ble_initialized = false;


// 创建特征值
static void create_char(uint16_t char_uuid, uint16_t *handle, esp_gatt_perm_t perm, 
                       esp_gatt_char_prop_t property) {
    esp_bt_uuid_t uuid = {
        .len = ESP_UUID_LEN_16,
        .uuid.uuid16 = char_uuid
    };
    
    esp_attr_control_t control = {
        .auto_rsp = ESP_GATT_AUTO_RSP
    };
    
    esp_attr_value_t value = {
        .attr_max_len = 100,
        .attr_len = 0,
        .attr_value = NULL
    };
    
    esp_err_t ret = esp_ble_gatts_add_char(gatts_profile.service_handle, &uuid, perm, property, &value, &control);
    if (ret != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Failed to add characteristic 0x%04X: %s", char_uuid, esp_err_to_name(ret));
    } else {
        ESP_LOGI(BLE_TAG, "Successfully added characteristic 0x%04X", char_uuid);
    }
}
// 初始化GATT服务
static void gatts_service_init(void) {
    // 定义服务ID
    esp_gatt_srvc_id_t service_id = {
        .id = {
            .uuid = {
                .len = ESP_UUID_LEN_16,
                .uuid = {.uuid16 = GATTS_SERVICE_UUID}  // 替换为你的服务UUID
            },
            .inst_id = 0x00,  // 实例ID，通常为0
        },
        .is_primary = true    // 是否是主要服务
    };

    // 创建服务
    esp_err_t ret = esp_ble_gatts_create_service(gatts_profile.gatts_if, &service_id,20);
    if (ret != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Start service failed: %s", esp_err_to_name(ret));
    } else {
        ESP_LOGI(BLE_TAG, "Service started successfully");
    }
}

// 启动GATT服务
static void start_gatt_service(void) {
    esp_err_t ret = esp_ble_gatts_start_service(gatts_profile.service_handle);
    if (ret != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Start service failed: %s", esp_err_to_name(ret));
    } else {
        ESP_LOGI(BLE_TAG, "GATT service started successfully");
        
        
        // 开始广播
        start_ble();
    }
}

// GATT事件处理
static void gatts_profile_event_handler(esp_gatts_cb_event_t event, 
                                       esp_gatt_if_t gatts_if, 
                                       esp_ble_gatts_cb_param_t *param) {
    switch (event) {
    case ESP_GATTS_REG_EVT: //应用创建成功
        ESP_LOGI(BLE_TAG, "REGISTER_APP_EVT, status %d, app_id %d", 
                param->reg.status, param->reg.app_id);
        gatts_profile.gatts_if = gatts_if;
        gatts_service_init();
        break;
    case ESP_GATTS_READ_EVT:
        ESP_LOGI(BLE_TAG, "GATTS_READ_EVT, handle %d, offset %d", 
                param->read.handle, param->read.offset);
        break;
    case ESP_GATTS_CREATE_EVT:  //服务创建成功
        ESP_LOGI(BLE_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d", 
                param->create.status, param->create.service_handle);
        if (param->create.status == ESP_GATT_OK) {
            gatts_profile.service_handle = param->create.service_handle;
            create_char(GATTS_CHAR_UUID_UUID_WIFI_CONFIG, &gatts_profile.char_handle_uuid_wifi, 
                            ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 
                            ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE);
            char_add_step = 0;
        }
        break;
    case ESP_GATTS_ADD_CHAR_EVT: //特征值添加成功
        ESP_LOGI(BLE_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d",
                param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
        if (param->add_char.status != ESP_GATT_OK) {
            ESP_LOGE(BLE_TAG, "Add characteristic failed");
            break;
        }
        switch (char_add_step) {
        case 0:
            
            // WiFi uuid配置特征
            gatts_profile.char_handle_uuid_wifi = param->add_char.attr_handle;
            ESP_LOGI(BLE_TAG, "WiFi Uuid config char added, handle: %d", gatts_profile.char_handle_uuid_wifi);
            
            // 添加wifi password配置特征
            create_char(GATTS_CHAR_UUID_PASSWORD_WIFI_CONFIG, &gatts_profile.char_handle_password_wifi, 
                            ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 
                            ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE);
            char_add_step++;
            break;
            
        case 1:
            // password 配置特征
            gatts_profile.char_handle_password_wifi = param->add_char.attr_handle;
            ESP_LOGI(BLE_TAG, "WIFI Password config char added, handle: %d", gatts_profile.char_handle_password_wifi);
            create_char(GATTS_CHAR_UUID_IP_CONFIG, &gatts_profile.char_handle_ip, 
                            ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 
                            ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE);
            
            // 添加状态特征
            // add_status_characteristic();
            char_add_step++;
            break;

        case 2:
            // IP配置特征
            gatts_profile.char_handle_ip = param->add_char.attr_handle;
            ESP_LOGI(BLE_TAG, "IP config char added, handle: %d", gatts_profile.char_handle_ip);
            create_char(GATTS_CHAR_UUID_GATEWAY_CONFIG, &gatts_profile.char_handle_gateway, 
                            ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 
                            ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE);
            
            char_add_step++;
            // char_add_step = 0; // 重置
            break;
        case 3:
            // 网关配置特征
            gatts_profile.char_handle_gateway = param->add_char.attr_handle;
            ESP_LOGI(BLE_TAG, "Gateway config char added, handle: %d", gatts_profile.char_handle_gateway);
            create_char(GATTS_CHAR_UUID_SUBNET_CONFIG, &gatts_profile.char_handle_subnet, 
                            ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 
                            ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE);
            char_add_step++;
            break;
        case 4:
            // 子网掩码配置特征
            gatts_profile.char_handle_subnet = param->add_char.attr_handle;
            ESP_LOGI(BLE_TAG, "Subnet config char added, handle: %d", gatts_profile.char_handle_subnet);
            // 启动服务
            start_gatt_service();
            char_add_step++;
            break;
            
        default:
            ESP_LOGW(BLE_TAG, "Unexpected add char step: %d", char_add_step);
            break;
    }
        break;
    case ESP_GATTS_WRITE_EVT:
        // 处理SSID接收
        printf("Write event: handle=%d, len=%d\n", param->write.handle, param->write.len);
        if (param->write.handle == gatts_profile.char_handle_uuid_wifi) {
            uint8_t *data = param->write.value;
            uint16_t len = param->write.len;
            
            if (len > 0) {
                // 清空并复制SSID，确保字符串终止
                memset(wifi_config.ssid, 0, sizeof(wifi_config.ssid));
                
                // 检查并去除ssid=前缀
                if (len >= 5 && strncmp((char*)data, "ssid=", 5) == 0) {
                    strncpy(wifi_config.ssid, (char*)data + 5, 
                            len - 5 < sizeof(wifi_config.ssid) - 1 ? len - 5 : sizeof(wifi_config.ssid) - 1);
                } else {
                    strncpy(wifi_config.ssid, (char*)data, 
                            len < sizeof(wifi_config.ssid) - 1 ? len : sizeof(wifi_config.ssid) - 1);
                }
                
                ESP_LOGI(BLE_TAG, "Received SSID: '%s'", wifi_config.ssid);
                update_status("已接收WiFi名称");
            }
        }
        // 处理密码接收
        else if (param->write.handle == gatts_profile.char_handle_password_wifi) {
            uint8_t *data = param->write.value;
            uint16_t len = param->write.len;
            
            if (len > 0) {
                // 清空并复制密码，确保字符串终止
                memset(wifi_config.password, 0, sizeof(wifi_config.password));
                
                // 检查并去除password=前缀
                if (len >= 9 && strncmp((char*)data, "password=", 9) == 0) {
                    strncpy(wifi_config.password, (char*)data + 9, 
                            len - 9 < sizeof(wifi_config.password) - 1 ? len - 9 : sizeof(wifi_config.password) - 1);
                } else {
                    strncpy(wifi_config.password, (char*)data, 
                            len < sizeof(wifi_config.password) - 1 ? len : sizeof(wifi_config.password) - 1);
                }
                
                ESP_LOGI(BLE_TAG, "Received Password：%s, length: %d", wifi_config.password,strlen(wifi_config.password));
                update_status("已接收WiFi密码");
                
                // 当收到密码后，认为配置完成，可以保存
                save_wifi_config(&wifi_config);
                update_status("WiFi配置已保存");
            }
        }
        else if (param->write.handle == gatts_profile.char_handle_ip) {
            // 处理IP配置
            uint8_t *data = param->write.value;
            uint16_t len = param->write.len;
            
            if (len > 0) {
                char config_str[128] = {0};
                memcpy(config_str, data, len > 127 ? 127 : len);
                ESP_LOGI(BLE_TAG, "Received IP config: %s", config_str);
                
                // 解析IP配置 
                char *ip_ptr = strstr(config_str, "ip=");                 
                if (ip_ptr) {
                    ip_ptr += 3; 
                    strncpy(network_config.ip, ip_ptr, sizeof(network_config.ip) - 1); 
                    ESP_LOGI(BLE_TAG, "Static IP: %s", network_config.ip);
                }
                update_status("IP配置已保存");
            }
        }
        else if (param->write.handle == gatts_profile.char_handle_gateway) {
            // 处理gw配置
            uint8_t *data = param->write.value;
            uint16_t len = param->write.len;
            if (len > 0) {
                char config_str[128] = {0};
                memcpy(config_str, data, len > 127 ? 127 : len);
                ESP_LOGI(BLE_TAG, "Received GW config: %s", config_str);
            
                char *sub_ptr = strstr(config_str, "gateway=");
                
                if (sub_ptr) {
                    sub_ptr += 8;
                    strncpy(network_config.gateway, sub_ptr, sizeof(network_config.gateway) - 1);
                    
                    ESP_LOGI(BLE_TAG, "GW: %s",network_config.gateway);
                }
                update_status("IP配置已保存");
            }
        }
        else if (param->write.handle == gatts_profile.char_handle_subnet) {
            // 处理IP配置
            uint8_t *data = param->write.value;
            uint16_t len = param->write.len;
            if (len > 0) {
                char config_str[128] = {0};
                memcpy(config_str, data, len > 127 ? 127 : len);
                ESP_LOGI(BLE_TAG, "Received Mask config: %s", config_str);
                char *sub_ptr = strstr(config_str, "subnet=");
                
                if (sub_ptr) {
                    sub_ptr += 7;
                    strncpy(network_config.subnet, sub_ptr, sizeof(network_config.subnet) - 1);
                    
                    ESP_LOGI(BLE_TAG, "Mask: %s",network_config.subnet);
                }
                
                save_network_config(&network_config);
                update_status("IP配置已保存");
            }
        }
        break;
    case ESP_GATTS_CONNECT_EVT:
        ESP_LOGI(BLE_TAG, "ESP_GATTS_CONNECT_EVT");
        ble_connected = true;
        update_status("设备已连接");
        break;
    case ESP_GATTS_DISCONNECT_EVT:
        ESP_LOGI(BLE_TAG, "ESP_GATTS_DISCONNECT_EVT");
        ble_connected = false;
        update_status("设备已断开");
        printf("正在设置静态IP");
        set_wifi_sta();
        set_static_ip_sta();
        break;
    default:
        break;
    }
}

// GAP事件处理
// static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
//     switch (event) {
//     case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
//         ESP_LOGI(BLE_TAG, "Advertising data set complete");
//         break;
//     case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//         if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
//             ESP_LOGE(BLE_TAG, "Advertising start failed");
//         } else {
//             ESP_LOGI(BLE_TAG, "Advertising started");
//         }
//         break;
//     default:
//         break;
//     }
// }

// 保存WiFi配置到NVS
void save_wifi_config(const my_wifi_config_t *config) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle);
    if (err != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Error opening NVS: %d", err);
        return;
    }
    
    err |= nvs_set_str(nvs_handle, "wifi_ssid", config->ssid);
    err |= nvs_set_str(nvs_handle, "wifi_password", config->password);
    err |= nvs_commit(nvs_handle);
    nvs_close(nvs_handle);
    
    if (err != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Error saving WiFi config");
    } else {
        ESP_LOGI(BLE_TAG, "WiFi config saved");
    }
}

// 保存网络配置到NVS
void save_network_config(const my_network_config_t *config) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle);
    if (err != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Error opening NVS: %d", err);
        return;
    }
    
    err |= nvs_set_str(nvs_handle, "ip", config->ip);
    err |= nvs_set_str(nvs_handle, "gateway", config->gateway);
    err |= nvs_set_str(nvs_handle, "subnet", config->subnet);
    err |= nvs_commit(nvs_handle);
    nvs_close(nvs_handle);
    
    if (err != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Error saving network config");
    } else {
        ESP_LOGI(BLE_TAG, "Network config saved");
    }
}

// // 从NVS加载配置
void load_config_from_nvs(void) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle);
    if (err != ESP_OK) {
        ESP_LOGI(BLE_TAG, "No saved config found");
        return;
    }
    
    // 加载WiFi配置
    size_t required_size;
    required_size=sizeof(wifi_config.ssid);
    err = nvs_get_str(nvs_handle, "wifi_ssid", NULL, &required_size);
    if (err == ESP_OK) {
        nvs_get_str(nvs_handle, "wifi_ssid", wifi_config.ssid, &required_size);
        required_size=sizeof(wifi_config.password);
        nvs_get_str(nvs_handle, "wifi_password", wifi_config.password, &required_size);
        ESP_LOGI(BLE_TAG, "Loaded WiFi config: %s,password: %s", wifi_config.ssid,wifi_config.password);
    }
    
    // 加载网络配置
    required_size=sizeof(network_config.ip);
    err = nvs_get_str(nvs_handle, "ip", network_config.ip, &required_size);
    if (err == ESP_OK) {
        required_size=sizeof(network_config.gateway);
        nvs_get_str(nvs_handle, "gateway", network_config.gateway, &required_size);
        required_size=sizeof(network_config.subnet);
        nvs_get_str(nvs_handle, "subnet", network_config.subnet, &required_size);
    }
    // required_size=sizeof(network_config.gateway);
    // nvs_get_str(nvs_handle, "gateway", network_config.gateway, &required_size);
    // required_size=sizeof(network_config.subnet);
    // nvs_get_str(nvs_handle, "subnet", network_config.subnet, &required_size);
    ESP_LOGI(BLE_TAG, "Loaded network config,  IP: %s, Gateway: %s, Subnet: %s", 
                 network_config.ip, network_config.gateway, network_config.subnet);
    
    nvs_close(nvs_handle);
}

// 更新状态特征值
void update_status(const char *status) {
    if (ble_connected && gatts_profile.char_handle_status != 0) {
        esp_ble_gatts_set_attr_value(gatts_profile.char_handle_status, 
                                   strlen(status), (uint8_t *)status);
    }
}
// 初始化BLE
void ble_init(void) {
    
    esp_err_t ret;
    
    // 初始化蓝牙控制器
    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        ESP_LOGE(BLE_TAG, "Bluetooth controller init failed: %s", esp_err_to_name(ret));
        return;
    }
    
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret) {
        ESP_LOGE(BLE_TAG, "Bluetooth controller enable failed: %s", esp_err_to_name(ret));
        return;
    }
    
    // 初始化Bluedroid
    ret = esp_bluedroid_init();
    if (ret) {
        ESP_LOGE(BLE_TAG, "Bluedroid init failed: %s", esp_err_to_name(ret));
        return;
    }
    
    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(BLE_TAG, "Bluedroid enable failed: %s", esp_err_to_name(ret));
        return;
    }
    
    // 注册GATT和GAP回调
    ret = esp_ble_gatts_register_callback(gatts_profile_event_handler);
    if (ret) {
        ESP_LOGE(BLE_TAG, "GATTS register callback failed: %s", esp_err_to_name(ret));
        return;
    }
    
    // ret = esp_ble_gap_register_callback(gap_event_handler);
    // if (ret) {
    //     ESP_LOGE(BLE_TAG, "GAP register callback failed: %s", esp_err_to_name(ret));
    //     return;
    // }
    // 创建GATT应用
    ret = esp_ble_gatts_app_register(0);
    if (ret) {
        ESP_LOGE(BLE_TAG, "GATTS app register failed: %s", esp_err_to_name(ret));
        return;
    }
    
    // 设置MTU
    ret = esp_ble_gatt_set_local_mtu(512);
    if (ret) {
        ESP_LOGE(BLE_TAG, "Set MTU failed: %s", esp_err_to_name(ret));
        return;
    }
    printf("server init\n");
    ble_initialized = true;
    ESP_LOGI(BLE_TAG, "BLE initialized successfully");
}

// 启动BLE广播
void start_ble(void) {
    //配置广播数据
    uint8_t adv_data[31] = {
        0x02, 0x01, 0x06, //ble标志：可发现模式，不支持BR/EDR
        0x03, 0x03, 0xFF,0x11, //Service UUID (0x11FF)
        0x0d, 0x09, 'E','S','P','3','2','_','C','o','n','f','i','g', // Device name
    };
    esp_err_t ret = esp_ble_gap_config_adv_data_raw(adv_data, sizeof(adv_data));
    if (ret != ESP_OK) {
        ESP_LOGE(BLE_TAG, "Failed to configure advertising data: %s", esp_err_to_name(ret));
        return;
    }
    
    adv_params.adv_int_min = 40;  // 最小广播间隔（ms）
    adv_params.adv_int_max = 60;  // 最大广播间隔（ms）
    esp_ble_gap_set_device_name("ESP32_Config");
    esp_ble_gap_start_advertising(&adv_params);
}